﻿using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Xml.Linq;

namespace ExcelAutomator
{
	public static class Extensions
	{

		public static string NameWithoutExtension(this FileInfo fileInfo)
		{
			return fileInfo.Name.Substring(0, fileInfo.Name.IndexOf(fileInfo.Extension));
		}

		public static bool IsNOE(this string value)
		{
			return string.IsNullOrEmpty(value);
		}

		public static string ExtractWorksheetNameFromAddress(this string value)
		{
			if (value.Contains('!'))
			{
				return value.Split('!')[0];
			}
			return value;
		}
	}

	public static class EnumExtensions
	{
		public static bool TryParse<T>(string value, out T outValue)
		{
			if(Enum.IsDefined(typeof(T), value))
			{
				object result = Enum.Parse(typeof (T), value, true);

				if (result.GetType() == typeof(T))
				{
					outValue = (T) result;
					return true;
				}
			}
			outValue = default(T);
			return false;
		}
	}


	public static class LinqExtensions
	{
		private static IEnumerable<TSource> DistinctByImpl<TSource, TKey>
				(IEnumerable<TSource> source,
				 Func<TSource, TKey> keySelector,
				 IEqualityComparer<TKey> comparer)
		{
			HashSet<TKey> knownKeys = new HashSet<TKey>(comparer);
			foreach (TSource element in source)
			{
				if (knownKeys.Add(keySelector(element)))
				{
					yield return element;
				}
			}
		}

		public static IEnumerable<TSource> DistinctBy<TSource, TKey>(this IEnumerable<TSource> source,
					 Func<TSource, TKey> keySelector)
		{

			return DistinctByImpl(source, keySelector, null);

		}
	}

	public static class XmlExtensions
	{
		public static bool TryGetAttributeValue(this XElement xElement, string name, out string value)
		{
			return TryGetAttributeValue(xElement, name, string.Empty, out value);
		}
		
		public static bool TryGetAttributeValue(this XElement xElement, string name, string ns, out string value)
		{
			var attribute = xElement.Attribute(XName.Get(name, ns));
			if (attribute != null)
			{
				value = attribute.Value;
				return true;
			}
			value = string.Empty;
			return false;
		}

		public static bool TryGetAttribute(this XElement xElement, string attributeName, out XAttribute attribute)
		{
			var attr = xElement.Attribute(attributeName);

			if (attr != null)
			{
				attribute = attr;
				return true;
			}

			attribute = null;
			return false;
		}

		

	}
}
